package com.sky.controller.user;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.github.pagehelper.Page;
import com.sky.dto.ArticleDTO;
import com.sky.dto.ArticlePageDTO;
import com.sky.dto.ArticleStatus;
import com.sky.dto.ArticleUpdateDTO;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.ArticleService;
import com.sky.vo.ArticleUpdateVO;
import com.sky.vo.ArticleVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController("UserArticleController")
@RequestMapping("/user/article")
@Tag(name = "文章相关接口")
public class ArticleController {


    private final ArticleService articleService;

    @Autowired
    public ArticleController(ArticleService articleService) {
        this.articleService = articleService;
    }



    /**
     * 分页查询文章
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询文章")
    public Result<PageResult> page(ArticlePageDTO articlePageDTO) {
        log.info("分页查询文章：{}",articlePageDTO);
        PageResult pageResult = articleService.page(articlePageDTO);
        return Result.success(pageResult);
    }




    /**
     * 根据id查询文章，Sentinel令牌桶限流防刷
     */
    @GetMapping("/{id}")
    @Operation(summary = "根据id查询文章")
    @SentinelResource(value = "/user/article/{id}",
            blockHandler = "getByIdBlockHandler",  // 限流降级方法
            blockHandlerClass = ArticleController.class)
    public Result getById(@PathVariable Long id) {
        log.info("根据id查询文章：{}",id);
        ArticleUpdateVO articleUpdateVO = articleService.getById(id);
        return Result.success(articleUpdateVO);
    }

    /**
     * 限流降级方法
     */
    public static Result<ArticleUpdateVO> getByIdBlockHandler(Long id, BlockException e) {
        log.warn("查询文章接口被限流:{}", id);
        return Result.error("请求过于频繁，请稍后再试！");
    }

    /**
     * 统计文章数量
     */
    @GetMapping("/count")
    @Operation(summary = "统计文章数量")
    public Result<Long> count() {
        log.info("统计文章数量");
        Long count = articleService.countArticle();
        return Result.success(count);
    }

    /**
     * 根据分类id查询该分类下的所有文章
     */
    @GetMapping("/list")
    @Operation(summary = "根据分类id查询该分类下的所有文章")
    public Result<List<ArticleVO>> list(Long categoryId) {
        log.info("根据分类id查询该分类下的所有文章：{}",categoryId);
        return Result.success(articleService.list(categoryId));
    }

    /**
     * 点赞文章
     */
    @PostMapping("/like/{id}")
    @Operation(summary = "点赞文章")
    public Result like(@PathVariable Long id) {
        log.info("点赞文章：{}",id);
        articleService.like(id);
        return Result.success();
    }

    /**
     * 取消点赞文章
     */
    @PostMapping("/dislike/{id}")
    @Operation(summary = "取消点赞文章")
    public Result dislike(@PathVariable Long id) {
        log.info("取消点赞文章：{}",id);
        articleService.dislike(id);
        return Result.success();
    }

    /**
     * 文章浏览数加一
     */
    @PostMapping("/view/{id}")
    @Operation(summary = "文章浏览数加一")
    public Result<Long> view(@PathVariable Long id) {
        log.info("文章浏览数加一：{}",id);
        Long commentCount = articleService.view(id);
        return Result.success(commentCount);
    }

    /**
     * 根据标签id分页查询该标签文章
     */
    @GetMapping("/pageTag")
    @Operation(summary = "根据标签id分页查询该标签文章")
    public Result<PageResult> pageByTagId(ArticlePageDTO articlePageDTO) {
        log.info("根据标签id分页查询该标签文章：{}",articlePageDTO);
        PageResult pageResult = articleService.pageByTagId(articlePageDTO);
        return Result.success(pageResult);
    }

    /**
     * 获取文章浏览量排名前10的文章
     */
    @GetMapping("/top")
    @Operation(summary = "获取文章浏览量排名前10的文章")
    public Result<List<ArticleVO>> topArticle() {
        log.info("获取文章浏览量排名前10的文章");
        List<ArticleVO> articleVOS = articleService.topArticle();
        return Result.success(articleVOS);
    }




}
